﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using Foothill.Common;
using Foothill.Common.Logging;
using Foothill.Model;

namespace Foothill.Service.UploadPhoto 
{
    public class UploadFileManager : System.Web.UI.Page, IUploadFileManager
    {
        private IImageProcessor _imageProcessor;

        public UploadFileManager(IImageProcessor imageProcessor)
        {
            _imageProcessor = imageProcessor;
        }
        
        // save a file to disk and return file name 
        public string SaveFile(string fileName, byte[] data)
        {
            string fileNameOnServer = string.Format("{0}{1}", Guid.NewGuid(), Path.GetExtension(fileName));

            SaveFileToDisk(fileNameOnServer, data);

            return fileNameOnServer;
        }

        public string SaveFile(string fileId, string fileName, byte[] data)
        {
            string fileNameOnServer = string.Format("{0}{1}", fileId, Path.GetExtension(fileName));

            if (!SaveFileToDisk(fileNameOnServer, data))
            {
                return string.Empty;
            }

            return fileNameOnServer;
        }

        public string SaveFile(HttpPostedFile file)
        {
            if (file == null)
            {
                return string.Empty;
            }

            string filePathOnServer = GetSaveAsPathOnServer(file.FileName);
            try
            {
                file.SaveAs(filePathOnServer);
                _imageProcessor.GenerateThumbnail(GlobalSettings.ThumbnailWidth, GlobalSettings.ThumbnailHeight, filePathOnServer);
                return filePathOnServer;
            }
            catch (Exception e)
            {
                Log.Error(FoothillModule.Service, "Failed to save file: " + filePathOnServer, e);
                return string.Empty;
            }
        }

        public void DeleteFile(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            try
            {
                File.Delete(path);
            }
            catch (Exception e)
            {
                Log.Error(FoothillModule.Service, "Failed to delete file: " + path, e);
            }
        }

        public bool ValidateUploadFileForUserProfileAndLogo(string fileName, int fileSize, out UploadPhotoValidationError error)
        {
            error = UploadPhotoValidationError.None;

            string ext = Path.GetExtension(fileName).ToLower();

            string[] allowedExtensions = {".jpg", ".gif", ".jpeg", ".png", ".bmp"};

            if (!allowedExtensions.Contains(ext))
            {
                error = UploadPhotoValidationError.InvalidExtension;
                return false;
            }

            const int max = 1024 * 2000;

            if (fileSize > max)
            {
                error = UploadPhotoValidationError.OverTheSizeLimit;
                return false;
            }

            return true;
        }

        internal string GetSaveAsPathOnServer(string uploadFileName)
        {
            string ext = Path.GetExtension(uploadFileName).ToLower();

            string fileName = string.Format("{0}{1}", Guid.NewGuid(), ext);
            string uploadPhotoFolder = Server.MapPath(GlobalSettings.UploadPhotoFolder);
            return Path.Combine(uploadPhotoFolder, fileName);
        }

        private bool SaveFileToDisk(string fileName, byte[] data)
        {
            bool saveFileSucceed = false;
            
            // save the file to disk, get the folder path on the server
            string uploadPhotoFolder = Server.MapPath(GlobalSettings.UploadPhotoFolder);
            string filePathOnServer = Path.Combine(uploadPhotoFolder, fileName);

            try
            {
                using (FileStream fs = new FileStream(filePathOnServer, FileMode.Create))
                {
                    fs.Write(data, 0, (int)data.Length);
                }

                // generate a thumbnail
                _imageProcessor.GenerateThumbnail(GlobalSettings.ThumbnailWidth, GlobalSettings.ThumbnailHeight, filePathOnServer);

                saveFileSucceed = true;
            }
            catch (Exception e)
            {
                Log.Error(FoothillModule.Service, "Fail when saving a file to disk", e);
            }

            return saveFileSucceed;
        }
    }
}
